package top.infopub.job.quartz.exec;


import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import top.infopub.cache.RedisCached;
import top.infopub.job.quartz.exec.base.BaseJob;
import top.infopub.util.RedisExpiresUtil;
import top.infopub.util.SpringContext;


/**
 * 过期Redis中定时zset-key和对应的hash-mapkey 的job </br>
 * 另参见：RedisExpiresUtil.java
 * @author Awoke
 * @version 2019年1月22日
 * @see RedisExpiresJob
 * @since
 */
public class RedisExpiresJob extends BaseJob {

    private static RedisCached redisCached;

    static {
        redisCached = SpringContext.getBean(RedisCached.class);
    }

    public RedisExpiresJob() {}

    @Override
    public void execute(JobExecutionContext context)
        throws JobExecutionException {
        // 获取定时已过期key的集合 （过期时间在当前时间之前，即需要过期了）
        String redisZsetKey = RedisExpiresUtil.COMMON_TIME_EXPIRES_ZSET;
        long expiredTime = System.currentTimeMillis();
        Set<Object> expiredKeys = redisCached.zrangeByScore(redisZsetKey, 0L, expiredTime);
        try {
            if (expiredKeys != null && expiredKeys.size() > 0) {
                // 删除定时已过期的Key
                redisCached.zremrangeByScore(redisZsetKey, 0L, expiredTime);
                // 解读定时已过期Key获取对应Hash的key名称和内部key
                Map<String, StringBuilder> delHashKeys = new HashMap<>();
                String[] ek = null;
                for (Object ekey : expiredKeys) {
                    String ekeyString = String.valueOf(ekey);
                    // 用“~”拆分已过期Key，获取对应Hash的key名称和 mapkey，并用“,”拼接小key
                    // imp:ip.rate:hash~192-168-0-90:register
                    if (StringUtils.contains(ekeyString, RedisExpiresUtil.HASH_JOIN_MAP_CHAR)) {
                        ek = ekeyString.split(RedisExpiresUtil.HASH_JOIN_MAP_CHAR);
                        if (delHashKeys.containsKey(ek[0])) {
                            delHashKeys.put(ek[0],
                                delHashKeys.get(ek[0]).append(",").append(ek[1]));
                        }
                        else {
                            delHashKeys.put(ek[0], new StringBuilder(ek[1]));
                        }
                    }
                }
                // 删出定时已过期Key对应的Hash内的键值对
                if (delHashKeys.size() > 0) {
                    Set<String> delKeys = delHashKeys.keySet();
                    for (String dkey : delKeys) {
                        redisCached.deleteHashCached(dkey,
                            delHashKeys.get(dkey).toString().split(","));
                    }
                }
            }
            long size = (expiredKeys != null ? expiredKeys.size() : 0L);
            if (size > 0) {
                log.debug("清除过期key数量：{}", size);
                logSucceed("清除过期key数量：" + size);
            }
        }
        catch (Exception e) {
            log.error("error expiredKeys, " + expiredKeys.toString(), e);
            logFail(e, true);
        }
    }
}
